" vim:ft=vim
"
" iter() and next()
"

Execute(iter() returns an iterator for String and List);
let input = [
      \ [],
      \ '',
      \ range(10),
      \ 'this is a str',
      \]

for i in input
  let x = object#iter(i)
  Log object#repr(x)
  Log object#dir(x)
  unlet i
endfor


Execute(iter() throws TypeError for non-iterable);
let non_iterable = [ 1, {}, function('tr'), ]
if object#util#has_special_variables()
  call extend(non_iterable, [v:none, v:false])
endif

if has('float')
  call add(non_iterable, 1.1)
endif

for X in non_iterable
  AssertThrows call object#iter(g:X)
  Assert g:vader_exception =~# 'TypeError'
endfor


Execute(iter() throws TypeError returns non-iter);
let cls = {}
function! cls.__iter__()
  return {}
endfunction

AssertThrows call object#iter(g:cls)
Log g:vader_exception
Assert g:vader_exception =~# 'TypeError'


Execute (Argument to iter() will be returned as it if it is already an iterator);
let x = object#iter('')
Assert x is# object#iter(x)


Execute(iter() throws WrongType if __iter__ is not a Funcref);
let cls = {
      \ '__iter__' : 1,
      \ }

AssertThrows call object#iter(g:cls)
Assert g:vader_exception =~# 'WrongType'


Execute(next() calls the next() method of an obj);
let cls = {}

function! cls.next()
  return 'called'
endfunction

AssertEqual object#next(cls), 'called'
